package Project;

import Hulppakket.*;

public class Camera {
	private Point3f eye;
	private Vector3f lookat;
	private Vector3f up;
	private Vector3f u;
	private Vector3f v;
	private Vector3f w;
	// NOTE: These are default values, and in the final program the FOV value should be used.
	private float d=0.5F;
	private float l=-0.8F;
	private float r=0.8F;
	private float t=0.6F;
	private float b=-0.6F;
	public Camera(Point3f eyev, Vector3f lookatv, Vector3f upv)
	{
		setEye(eyev);
		setLookat(lookatv);
		up = upv;
		this.orthoNormalise();
	}
	/**
	 * Orthonormalise the u,v,w axes of the camera
	 * @return
	 */
	public void orthoNormalise()
	{
		Vector3f gaze = Vector3f.Min(this.getLookat(),new Vector3f(this.getEye()));
		gaze = gaze.normalise();
		w = gaze;
		w = w.multiply(-1);
		u = Vector3f.cross(this.getUp(), w);
		u = u.normalise();
		v = Vector3f.cross(w, u);
		v = v.normalise();
		System.out.println(w+" "+u+" "+v);
	}
	/**
	 * Generate ray
	 * @return
	 */
	public Ray generateRay(int i, int j, int nx, int ny)
	{
		float cu = (float) (l+(r-l)*(nx-i+0.5)/nx);
		float cv = (float) (b+(t-b)*(ny-j+0.5)/ny);
		Vector3f dvec = Vector3f.Plus(w.multiply((-1F*d)),u.multiply(cu));
		dvec = Vector3f.Plus(dvec, v.multiply(cv));
		Ray r = new Ray(this.getEye(),dvec);
		return r;
	}
	public Point3f getEye() {
		return eye;
	}
	public void setEye(Point3f eye) {
		this.eye = eye;
	}
	public Vector3f getLookat() {
		return lookat;
	}
	public void setLookat(Vector3f lookat) {
		this.lookat = lookat;
	}
	public Vector3f getUp() {
		return up;
	}
	public void setUp(Vector3f up) {
		this.up = up;
	}
}
